package cc.owoo.godpen.analysis.css;

import cc.owoo.godpen.analysis.html.Element;

import java.util.LinkedList;
import java.util.Queue;

/**
 * 抽象选择器，该选择器可能是单个选择器，也可能是一个选择器组
 * Created by nimensei
 * 2022-06-01 上午 01:32
 */
public abstract class Selector {
    public static final ChildSelector CHILD_SELECTOR = new ChildSelector();// 在执行选择器节点时，切换至子元素选择器

    /**
     * 解析选择器表达式
     *
     * @param string 选择器表达式，如果为空则返回null
     * @return 选择器对象，如果选择器条数为1则返回单条选择器，如果选择器大于1则返回选择器组，否则返回null
     */
    public static Selector parse(String string) {
        if (string == null || string.length() == 0)
            return new SelectorSingle();
        StyleStringAnalysis analysis = new StyleStringAnalysis(string.toCharArray());
        SelectorGroup selectorGroup = analysis.nextSelectorGroup('{');
        if (selectorGroup == null || selectorGroup.size() == 0)
            return new SelectorSingle();
        if (selectorGroup.size() == 1)
            return selectorGroup.get(0);
        return selectorGroup;
    }

    /**
     * 对元素进行选择，返回选择器执行的结果
     *
     * @param elements 需要进行选择的元素
     */
    public LinkedList<Element> select(Element... elements) {
        LinkedList<Element> elementList = new LinkedList<>();
        if (elements == null)
            return elementList;
        for (Element element : elements)
            if (element != null)
                elementList.add(element);
        select(elementList);
        return elementList;
    }

    /**
     * 对元素进行选择，只保留符合选择器结果的元素
     *
     * @param elements 需要进行选择的元素集合
     */
    public abstract void select(Queue<Element> elements);

    /**
     * 序列化选择器
     *
     * @param string  序列化字符串
     * @param retract 缩进
     * @param format  是否格式化代码
     * @return 是否有效的序列化了
     */
    public abstract boolean stringify(StringBuilder string, String retract, boolean format);

    /**
     * 将选择器序列化
     *
     * @return 序列化后的字符串
     */
    public String stringify() {
        StringBuilder string = new StringBuilder();
        stringify(string, null, false);
        return string.toString();
    }

    /**
     * 将选择器序列化，并进行格式化处理
     *
     * @return 序列化后的字符串
     */
    public String stringifyFormat() {
        StringBuilder string = new StringBuilder();
        stringify(string, null, true);
        return string.toString();
    }
}
